package com.mmc.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mmc.common.result.Result;
import com.mmc.entity.Role;
import com.mmc.service.RoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
 * 角色控制器
 *
 * @author kunfe
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/roles")
@RequiredArgsConstructor
@SaCheckLogin
@Tag(name = "角色管理", description = "角色管理相关接口")
public class RoleController {

    private final RoleService roleService;

    @Operation(summary = "分页查询角色")
    @GetMapping("/page")
    public Result<Page<Role>> getRolePage(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String roleName,
            @RequestParam(required = false) String roleCode,
            @RequestParam(required = false) Integer status) {
        
        Page<Role> page = new Page<>(current, size);
        Page<Role> result = roleService.getRolePage(page, roleName, roleCode, status);
        
        return Result.ok(result);
    }

    @Operation(summary = "获取所有启用的角色")
    @GetMapping("/enabled")
    public Result<List<Role>> getEnabledRoles() {
        List<Role> roles = roleService.getEnabledRoles();
        return Result.ok(roles);
    }

    @Operation(summary = "获取角色详情")
    @GetMapping("/{id}")
    public Result<Role> getRoleById(@PathVariable Long id) {
        Role role = roleService.getById(id);
        if (role != null) {
            role.setMenuIds(roleService.getRoleMenuIds(id));
        }
        return Result.ok(role);
    }

    @Operation(summary = "新增角色")
    @PostMapping
    public Result<Void> createRole(@Valid @RequestBody CreateRoleRequest request) {
        Role role = new Role();
        role.setRoleName(request.getRoleName());
        role.setRoleCode(request.getRoleCode());
        role.setDescription(request.getDescription());
        role.setRoleType(request.getRoleType());
        role.setDataScope(request.getDataScope());
        role.setSort(request.getSort());
        role.setStatus(request.getStatus());
        role.setRemark(request.getRemark());
        role.setMenuIds(request.getMenuIds());
        
        boolean success = roleService.createRole(role);
        return success ? Result.ok() : Result.fail("新增失败");
    }

    @Operation(summary = "更新角色")
    @PutMapping("/{id}")
    public Result<Void> updateRole(@PathVariable Long id, @Valid @RequestBody UpdateRoleRequest request) {
        Role role = new Role();
        role.setId(id);
        role.setRoleName(request.getRoleName());
        role.setRoleCode(request.getRoleCode());
        role.setDescription(request.getDescription());
        role.setRoleType(request.getRoleType());
        role.setDataScope(request.getDataScope());
        role.setSort(request.getSort());
        role.setStatus(request.getStatus());
        role.setRemark(request.getRemark());
        role.setMenuIds(request.getMenuIds());
        
        boolean success = roleService.updateRole(role);
        return success ? Result.ok() : Result.fail("更新失败");
    }

    @Operation(summary = "删除角色")
    @DeleteMapping("/{id}")
    public Result<Void> deleteRole(@PathVariable Long id) {
        boolean success = roleService.deleteRole(id);
        return success ? Result.ok() : Result.fail("删除失败");
    }

    @Operation(summary = "批量删除角色")
    @DeleteMapping("/batch")
    public Result<Void> batchDeleteRole(@Valid @RequestBody BatchDeleteRequest request) {
        boolean success = roleService.batchDeleteRole(request.getIds());
        return success ? Result.ok() : Result.fail("删除失败");
    }

    @Operation(summary = "启用/禁用角色")
    @PutMapping("/{id}/status")
    public Result<Void> changeStatus(@PathVariable Long id, @RequestBody ChangeStatusRequest request) {
        boolean success = roleService.changeStatus(id, request.getStatus());
        return success ? Result.ok() : Result.fail("操作失败");
    }

    @Operation(summary = "分配菜单权限")
    @PutMapping("/{id}/menus")
    public Result<Void> assignMenus(@PathVariable Long id, @Valid @RequestBody AssignMenusRequest request) {
        boolean success = roleService.assignMenus(id, request.getMenuIds());
        return success ? Result.ok() : Result.fail("分配失败");
    }

    @Operation(summary = "获取角色菜单权限")
    @GetMapping("/{id}/menus")
    public Result<List<Long>> getRoleMenus(@PathVariable Long id) {
        List<Long> menuIds = roleService.getRoleMenuIds(id);
        return Result.ok(menuIds);
    }

    @Operation(summary = "检查角色编码是否存在")
    @GetMapping("/check-code")
    public Result<Boolean> checkRoleCode(
            @RequestParam String roleCode,
            @RequestParam(required = false) Long excludeId) {
        boolean exists = roleService.existsRoleCode(roleCode, excludeId);
        return Result.ok(exists);
    }

    // DTO类
    @Data
    public static class CreateRoleRequest {
        @NotBlank(message = "角色名称不能为空")
        private String roleName;
        
        @NotBlank(message = "角色编码不能为空")
        private String roleCode;
        
        private String description;
        
        @NotNull(message = "角色类型不能为空")
        private Integer roleType;
        
        @NotNull(message = "数据权限不能为空")
        private Integer dataScope;
        
        private Integer sort = 0;
        private Integer status = 1;
        private String remark;
        private List<Long> menuIds;
    }

    @Data
    public static class UpdateRoleRequest {
        @NotBlank(message = "角色名称不能为空")
        private String roleName;
        
        @NotBlank(message = "角色编码不能为空")
        private String roleCode;
        
        private String description;
        
        @NotNull(message = "角色类型不能为空")
        private Integer roleType;
        
        @NotNull(message = "数据权限不能为空")
        private Integer dataScope;
        
        private Integer sort;
        private Integer status;
        private String remark;
        private List<Long> menuIds;
    }

    @Data
    public static class BatchDeleteRequest {
        @NotEmpty(message = "删除ID列表不能为空")
        private List<Long> ids;
    }

    @Data
    public static class ChangeStatusRequest {
        @NotNull(message = "状态不能为空")
        private Integer status;
    }

    @Data
    public static class AssignMenusRequest {
        private List<Long> menuIds;
    }
} 